package com.lynkin.realizedream.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.lynkin.realizedream.constant.DreamConstant;
import com.lynkin.realizedream.entity.DoubleColorBall;
import com.lynkin.realizedream.service.RealizeDreamService;
import com.lynkin.realizedream.utils.GetLottery;
import com.lynkin.realizedream.utils.RedisUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lingjian
 * @description: TODO
 * @date 2022/4/2 13:20
 */
@Service
public class RealizeDreamServiceImpl implements RealizeDreamService {


    @Autowired
    private RedisUtils redisUtils;



    String lastDreamCode = "";

    public void setLastDreamCode() {
        try {
            String nowDay = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
//            redisUtils.remove(DreamConstant.DOUBLE_COLOR_BALL + nowDay);
            if (!redisUtils.exists(DreamConstant.DOUBLE_COLOR_BALL + nowDay)) {
                List<DoubleColorBall> beforeDCB = GetLottery.getBeforeDCB(21001);
                redisUtils.set(DreamConstant.DOUBLE_COLOR_BALL + nowDay, beforeDCB);
            }

            JSONArray jsonArray = JSONUtil.parseArray(redisUtils.get(DreamConstant.DOUBLE_COLOR_BALL + nowDay));
            List<DoubleColorBall> doubleColorBalls = jsonArray.toList(DoubleColorBall.class);
//            System.out.println(doubleColorBalls);
            if (doubleColorBalls != null && doubleColorBalls.size() != 0) {
                DoubleColorBall doubleColorBall = doubleColorBalls.get(0);
                this.lastDreamCode = doubleColorBall.getRedBall_One()
                        + "," + (doubleColorBall.getRedBall_Two() == 0 ? 12 : doubleColorBall.getRedBall_Two())
                        + "," + doubleColorBall.getRedBall_Three()
                        + "," + doubleColorBall.getRedBall_Four()
                        + "," + doubleColorBall.getRedBall_Fives()
                        + "," + doubleColorBall.getRedBall_Six()
                        + "," + doubleColorBall.getBlueBall_One();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 往期回顾
     */
    public List<DoubleColorBall> oldCodes() {
        String nowDay = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
//            redisUtils.remove(DreamConstant.DOUBLE_COLOR_BALL + nowDay);
        if (!redisUtils.exists(DreamConstant.DOUBLE_COLOR_BALL + nowDay)) {
            List<DoubleColorBall> beforeDCB = null;
            try {
                beforeDCB = GetLottery.getBeforeDCB(21001);
            } catch (Exception e) {
                e.printStackTrace();
            }
            redisUtils.set(DreamConstant.DOUBLE_COLOR_BALL + nowDay, beforeDCB);
        }

        JSONArray jsonArray = JSONUtil.parseArray(redisUtils.get(DreamConstant.DOUBLE_COLOR_BALL + nowDay));
        return jsonArray.toList(DoubleColorBall.class);
    }

    /**
     * 获取神秘代码
     * @return
     */
    public String getMysteriousCode() {
        this.setLastDreamCode();
        List<Integer> randomCode = getRandomCode();

        String[] split = lastDreamCode.split(",");
        List<Integer> lastDreamCode = new ArrayList<>();
        for (String s : split) {
            lastDreamCode.add(Integer.valueOf(s));
        }

        while (!isContinuous(randomCode) || !isDuplicate(randomCode, lastDreamCode)) {
            lastDreamCode = getRandomCode();
        }

        String redCode = "";
        for (Integer integer : randomCode) {
            redCode += integer + ",";
        }
        String blueCode = String.valueOf((int) (1 + Math.random() * (16 - 1)) + 1);
        return redCode + blueCode;
    }

    /**
     * 随机指定范围内N个不重复的数
     * 利用HashSet的特征，只能存放不同的值
     * @param min 指定范围最小值
     * @param max 指定范围最大值
     * @param n 随机数个数
     * @param HashSet<Integer> set 随机数结果集
     */
    public void randomSet(int min, int max, int n, HashSet<Integer> set) {
        if (n > (max - min + 1) || max < min) {
            return;
        }
        for (int i = 0; i < n; i++) {
            // 调用Math.random()方法
            int num = (int) (1 + Math.random() * (max - min)) + min;
            set.add(num);// 将不同的数存入HashSet中
        }
        int setSize = set.size();
        // 如果存入的数小于指定生成的个数，则调用递归再生成剩余个数的随机数，如此循环，直到达到指定大小
        if (setSize < n) {
            randomSet(min, max, n - setSize, set);// 递归
        }
    }

    /**
     * 获取红球随机数
     * @return
     */
    public List<Integer> getRandomCode() {
        HashSet<Integer> set = new HashSet<>();
        randomSet(1, 32, 6, set);
        List<Integer> randomCode = set.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
        return randomCode;
    }

    /**
     * 判断数字是否存在连续
     * @param collect
     * @return
     */
    public boolean isContinuous(List<Integer> collect) {
        for (int i = 1; i < collect.size(); i++) {
            if (collect.get(i - 1) + 1 == collect.get(i)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断数字是否有重复
     * @param collect1
     * @param collect2
     * @return
     */
    public boolean isDuplicate(List<Integer> collect1, List<Integer> collect2) {
        for (int i = 0, j = 0; i < 6 && j < 6; ) {
            if (collect1.get(i) > collect2.get(j)) {
                j++;
            } else if (collect1.get(i) < collect2.get(j)) {
                i++;
            } else {
                return true;
            }
        }
        return false;
    }

}
